use super::*;
use crate::NumberOfNodes;
use crate::crypto::tests::set_of;
use ic_crypto_internal_types::curves::bls12_381::{FrBytes, G1Bytes, G2Bytes};
use ic_crypto_internal_types::sign::threshold_sig::ni_dkg::ni_dkg_groth20_bls12_381;
use ic_crypto_internal_types::sign::threshold_sig::ni_dkg::ni_dkg_groth20_bls12_381::{
    Dealing, EncryptedShares, NUM_CHUNKS, NUM_ZK_REPETITIONS, PublicCoefficientsBytes, ZKProofDec,
    ZKProofShare,
};
use ic_management_canister_types_private::VetKdCurve;
use std::str::FromStr;

#[test]
fn should_correctly_convert_csp_dkg_dealing_to_dkg_dealing() {
    let csp_dealing = csp_dealing();

    assert_eq!(
        NiDkgDealing::from(csp_dealing.clone()),
        NiDkgDealing {
            internal_dealing: csp_dealing
        }
    );
}

#[test]
fn should_correctly_convert_dkg_dealing_to_csp_dkg_dealing() {
    let csp_dealing = csp_dealing();
    let dealing = NiDkgDealing {
        internal_dealing: csp_dealing.clone(),
    };

    assert_eq!(CspNiDkgDealing::from(dealing), csp_dealing);
}

#[test]
fn should_correctly_convert_ni_dkg_transcript_to_csp_dkg_transcript() {
    let csp_dkg_transcript = empty_ni_csp_dkg_transcript();
    let dkg_transcript = transcript_with_internal_csp_transcript(&csp_dkg_transcript);

    assert_eq!(
        CspNiDkgTranscript::from(&dkg_transcript),
        csp_dkg_transcript
    );
}

#[test]
// This is explicitly tested since this appears in debug log messages. The
// message should be well readable and in particular contain hex encodings where
// applicable.
fn should_correctly_format_dealing_display_message() {
    let dealing = NiDkgDealing::dummy_dealing_for_tests(0);

    let display_text = format!("{dealing}");

    let expected_text = "NiDkgDealing { internal_dealing: Groth20_Bls12_381(Dealing { \
        public_coefficients: PublicCoefficientsBytes { coefficients: [] }, ciphertexts: FsEncryptionCiphertextBytes { \
         rand_r: [G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)], \
          rand_s: [G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)], \
          rand_z: [G2(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G2(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G2(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G2(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G2(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G2(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G2(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G2(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G2(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G2(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G2(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G2(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G2(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G2(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G2(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G2(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)], \
          ciphertext_chunks: [[G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)]] }, \
          zk_proof_decryptability: ZKProofDec { first_move_y0: G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          first_move_b: [G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)], \
          first_move_c: [G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
          G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)], \
          second_move_d: [G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
           G1(0x010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101)], \
           second_move_y: G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
           response_z_r: [Fr(\"0000000000000000000000000000000000000000000000000000000000000000\")], \
           response_z_s: [Fr(\"0000000000000000000000000000000000000000000000000000000000000000\"), \
           Fr(\"0000000000000000000000000000000000000000000000000000000000000000\"), \
           Fr(\"0000000000000000000000000000000000000000000000000000000000000000\"), \
           Fr(\"0000000000000000000000000000000000000000000000000000000000000000\"), \
           Fr(\"0000000000000000000000000000000000000000000000000000000000000000\"), \
           Fr(\"0000000000000000000000000000000000000000000000000000000000000000\"), \
           Fr(\"0000000000000000000000000000000000000000000000000000000000000000\"), \
           Fr(\"0000000000000000000000000000000000000000000000000000000000000000\"), \
           Fr(\"0000000000000000000000000000000000000000000000000000000000000000\"), \
           Fr(\"0000000000000000000000000000000000000000000000000000000000000000\"), \
           Fr(\"0000000000000000000000000000000000000000000000000000000000000000\"), \
           Fr(\"0000000000000000000000000000000000000000000000000000000000000000\"), \
           Fr(\"0000000000000000000000000000000000000000000000000000000000000000\"), \
           Fr(\"0000000000000000000000000000000000000000000000000000000000000000\"), \
           Fr(\"0000000000000000000000000000000000000000000000000000000000000000\"), \
           Fr(\"0000000000000000000000000000000000000000000000000000000000000000\"), \
           Fr(\"0000000000000000000000000000000000000000000000000000000000000000\"), \
           Fr(\"0000000000000000000000000000000000000000000000000000000000000000\"), \
           Fr(\"0000000000000000000000000000000000000000000000000000000000000000\"), \
           Fr(\"0000000000000000000000000000000000000000000000000000000000000000\"), \
           Fr(\"0000000000000000000000000000000000000000000000000000000000000000\"), \
           Fr(\"0000000000000000000000000000000000000000000000000000000000000000\"), \
           Fr(\"0000000000000000000000000000000000000000000000000000000000000000\"), \
           Fr(\"0000000000000000000000000000000000000000000000000000000000000000\"), \
           Fr(\"0000000000000000000000000000000000000000000000000000000000000000\"), \
           Fr(\"0000000000000000000000000000000000000000000000000000000000000000\"), \
           Fr(\"0000000000000000000000000000000000000000000000000000000000000000\"), \
           Fr(\"0000000000000000000000000000000000000000000000000000000000000000\"), \
           Fr(\"0000000000000000000000000000000000000000000000000000000000000000\"), \
           Fr(\"0000000000000000000000000000000000000000000000000000000000000000\"), \
           Fr(\"0000000000000000000000000000000000000000000000000000000000000000\"), \
           Fr(\"0000000000000000000000000000000000000000000000000000000000000000\")], \
           response_z_b: Fr(\"0000000000000000000000000000000000000000000000000000000000000000\") }, \
           zk_proof_correct_sharing: ZKProofShare { \
           first_move_f: G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
           first_move_a: G2(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
           first_move_y: G1(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000), \
           response_z_r: Fr(\"0000000000000000000000000000000000000000000000000000000000000000\"), \
           response_z_a: Fr(\"0000000000000000000000000000000000000000000000000000000000000000\") } }) }";

    assert_eq!(display_text, expected_text);
}

#[test]
fn should_correctly_format_ni_dkg_id() {
    let vetkd_key_id = VetKdKeyId {
        curve: VetKdCurve::Bls12_381_G2,
        name: "abcdefg".to_string(),
    };

    let nidkg_mpkid = NiDkgMasterPublicKeyId::VetKd(vetkd_key_id);

    assert_eq!(
        MasterPublicKeyId::from_str(&format!("{nidkg_mpkid}")),
        Ok(MasterPublicKeyId::from(nidkg_mpkid))
    );
}

fn transcript_with_internal_csp_transcript(
    csp_dkg_transcript: &CspNiDkgTranscript,
) -> NiDkgTranscript {
    NiDkgTranscript {
        dkg_id: NiDkgId {
            start_block_height: Height::new(42),
            dealer_subnet: SubnetId::from(PrincipalId::new_subnet_test_id(1)),
            dkg_tag: NiDkgTag::LowThreshold,
            target_subnet: NiDkgTargetSubnet::Local,
        },
        threshold: NiDkgThreshold::new(NumberOfNodes::new(2)).unwrap(),
        committee: NiDkgReceivers::new(set_of(&[NodeId::new(PrincipalId::new_subnet_test_id(1))]))
            .unwrap(),
        registry_version: Default::default(),
        internal_csp_transcript: csp_dkg_transcript.clone(),
    }
}

fn csp_dealing() -> CspNiDkgDealing {
    CspNiDkgDealing::Groth20_Bls12_381(Dealing {
        public_coefficients: PublicCoefficientsBytes {
            coefficients: vec![],
        },
        ciphertexts: EncryptedShares {
            rand_r: [G1Bytes([1; G1Bytes::SIZE]); NUM_CHUNKS],
            rand_s: [G1Bytes([12; G1Bytes::SIZE]); NUM_CHUNKS],
            rand_z: [G2Bytes([123; G2Bytes::SIZE]); NUM_CHUNKS],
            ciphertext_chunks: vec![[G1Bytes([234; G1Bytes::SIZE]); NUM_CHUNKS]],
        },
        zk_proof_decryptability: zk_proof_dec(),
        zk_proof_correct_sharing: zk_proof_share(),
    })
}

pub fn zk_proof_dec() -> ZKProofDec {
    let fr = FrBytes([0u8; FrBytes::SIZE]);
    let g1 = G1Bytes([0u8; G1Bytes::SIZE]);

    ZKProofDec {
        first_move_y0: g1,
        first_move_b: [g1; NUM_ZK_REPETITIONS],
        first_move_c: [g1; NUM_ZK_REPETITIONS],
        second_move_d: Vec::new(),
        second_move_y: g1,
        response_z_r: Vec::new(),
        response_z_s: [fr; NUM_ZK_REPETITIONS],
        response_z_b: fr,
    }
}

pub fn zk_proof_share() -> ZKProofShare {
    let fr = FrBytes([0u8; FrBytes::SIZE]);
    let g1 = G1Bytes([0u8; G1Bytes::SIZE]);
    let g2 = G2Bytes([0u8; G2Bytes::SIZE]);

    ZKProofShare {
        first_move_f: g1,
        first_move_a: g2,
        first_move_y: g1,
        response_z_r: fr,
        response_z_a: fr,
    }
}

fn empty_ni_csp_dkg_transcript() -> CspNiDkgTranscript {
    CspNiDkgTranscript::Groth20_Bls12_381(ni_dkg_groth20_bls12_381::Transcript {
        public_coefficients: PublicCoefficientsBytes {
            coefficients: vec![],
        },
        receiver_data: Default::default(),
    })
}
